/*
 * 文件名：ConfigLoader.java
 * 版权：Copyright by www.huawei.com
 * 描述：
 * 修改人：Administrator
 * 修改时间：2012-4-28
 * 跟踪单号：
 * 修改单号：
 * 修改内容：
 */
package com.chinasoftosg.sicap.scheduling.job;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 解析config配置文件
 *    生成话单表的Insert语句<br/>
 *    解析配置文件的ftp配置<br/>
 *    解析配置文件的文本解析规则配置<br/>
 * @author guo
 * @2012-4-26
 */

public class ConfigLoader
{
    
    // field define
    
    /***
     * 批量插入的最大提交数
     */
    private int maxCommitNumber;
    
    /***
     * 解析规则
     */
    private String rule;
    
    /***
     * 话单数据表名
     */
    private String tableName;
    
    /***
     * 主键
     */
    private String primaryKey;
    
    /***
     * 主键自动增长的 序列名称
     */
    private String sequenceName;
    
    /***
     * 话单数据表字段数组
     */
    private String[] columns;
    
    /***
     * 话单数据库表名
     */
    private String[] types;
    
    /***
     * 解析后的数字序号
     */
    private int[] splitIndexs;
    
    
    /***
     * FTP配置项
     */
    private List<Map<String,String>> configList;
    
    /***
     * 日志文件
     */
    private Logger logger = Logger.getLogger(this.getClass());
    
    /***
     * 配置文件名
     */
    public final static String CONFIG_FILE_PATH = "billing_config.xml";
    
    // main method
    
    public ConfigLoader() {}
    
    
    /***
     * 
     * Description: ConfigLoader类的初始化<br>
     * 1、读取xml文件<br>
     * 2、解析xml文件<br>
     * 
     * 返回异常信息
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException 
     * @see
     */
    public void init()throws ParserConfigurationException,SAXException,IOException
    {
        logger.info("ConfigLoader init method ");
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc;
        InputStream in = ConfigLoader.class.getClassLoader()
                .getResourceAsStream(CONFIG_FILE_PATH);
        doc = db.parse(in);
        Element eroot = (Element)doc.getElementsByTagName("root").item(0);
        parseTableConfig(eroot);
        parseFtpConfig(eroot);
    }
    
    /***
     * 
     * Description: 解析配置文件的字符串解析规则和数据库表和字段<br>
     * @param eroot 
     * @see
     */
    private void parseTableConfig(Element eroot)
    {
        logger.info("ConfigLoader parseTableConfig method ");
        Element etableConfigs = (Element)eroot.getElementsByTagName("tableConfigs")
                .item(0);
        Element etableConfig = (Element)etableConfigs.getElementsByTagName("tableConfig")
                .item(0);
        maxCommitNumber = Integer.parseInt(etableConfig.getAttribute("maxCommitNumber"));
        rule = etableConfig.getAttribute("rule");
        tableName = etableConfig.getAttribute("tableName");
        primaryKey = etableConfig.getAttribute("primaryKey");
        sequenceName = etableConfig.getAttribute("sequence");
        
        int length = etableConfig.getElementsByTagName("column").getLength();
        
        columns = new String[length];
        splitIndexs = new int[length];
        types = new String[length];
        for (int i = 0; i < length; i++)
        {
            Element ecolumn = (Element)etableConfig.getElementsByTagName("column")
                    .item(i);
            
            String columnName = ecolumn.getAttribute("columnName");
            columns[i] = columnName;
            
            String type = ecolumn.getAttribute("type");
            types[i] = type;
            
            String splitIndex = ecolumn.getAttribute("splitIndex");
            splitIndexs[i] = Integer.parseInt(splitIndex);
        }
    }
    
    
    /***
     * 
     * 解析配置文件中 
     *  <ftpConfigs> </ftpConfigs>
     * @param 配置文件Root节点 
     * @see
     */
    private void parseFtpConfig(Element eroot)
    {
        logger.info("ConfigLoader parseFtpConfig method ");
        Element eftpConfigs = (Element)eroot.getElementsByTagName("ftpConfigs")
                .item(0);
        NodeList eftpConfigNodeList = eftpConfigs.getElementsByTagName("ftpConfig");
        int length =  eftpConfigNodeList.getLength();
        System.out.println("length="+length); 
        configList = new ArrayList<Map<String,String>>();
        Map<String, String> map = null;
        for(int i = 0;i<length;i++){
            map = new HashMap<String, String>();
            Element eftpConfig = (Element)eftpConfigNodeList.item(i);
            map.put("ip", eftpConfig.getAttribute("ip"));
            map.put("userName", eftpConfig.getAttribute("userName"));
            map.put("password", eftpConfig.getAttribute("password"));
            map.put("port", eftpConfig.getAttribute("port"));
            map.put("remote", eftpConfig.getAttribute("remote"));
            map.put("local", eftpConfig.getAttribute("local"));
            configList.add(map);
        }
    }
    
    
    /***
     * 
     * Description: 通过解析配置文件，得到数据库名，字段名称和字段类型<br>
     * 生成SQL Insert语句<br>
     * @return 
     *         insert 语句
     */
    public String getInsertSql()
    {
        logger.info("ConfigLoader getInsertSql method ");
        int length = columns.length;
        StringBuffer sb = new StringBuffer();
        sb.append(" INSERT INTO ")
                .append(tableName)
                .append(" (")
                .append(primaryKey)
                .append(",");
        StringBuffer sbTemp = new StringBuffer();
        sbTemp.append(" (").append(sequenceName).append(".nextval,");
        
        for (int i = 0; i < length; i++)
        {
            sb.append(columns[i]);
            sbTemp.append("?");
            if (i < length - 1)
            {
                sb.append(",");
                sbTemp.append(",");
            }
        }
        sbTemp.append(") ");
        sb.append(") VALUES ");
        String sql = sb.toString() + sbTemp.toString();
        
        return sql;
    }
    
    // get set methods
    
    public int getMaxCommitNumber()
    {
        return maxCommitNumber;
    }
    
    public void setMaxCommitNumber(int maxCommitNumber)
    {
        this.maxCommitNumber = maxCommitNumber;
    }
    
    public String getRule()
    {
        return rule;
    }
    
    public void setRuleId(String rule)
    {
        this.rule = rule;
    }
    
    public String[] getColumns()
    {
        return columns;
    }
    
    public void setColumns(String[] columns)
    {
        this.columns = columns;
    }
    
    public int[] getSplitIndexs()
    {
        return splitIndexs;
    }
    
    public void setSplitIndexs(int[] splitIndexs)
    {
        this.splitIndexs = splitIndexs;
    }
    
    public static String getConfigFilePath()
    {
        return CONFIG_FILE_PATH;
    }
    
    public String getTableName()
    {
        return tableName;
    }
    
    public void setTableName(String tableName)
    {
        this.tableName = tableName;
    }
    
    public String[] getTypes()
    {
        return types;
    }
    
    public void setTypes(String[] types)
    {
        this.types = types;
    }
    
    public String getPrimaryKey()
    {
        return primaryKey;
    }
    
    public void setPrimaryKey(String primaryKey)
    {
        this.primaryKey = primaryKey;
    }
    
    public void setRule(String rule)
    {
        this.rule = rule;
    }
    
    public String getSequenceName()
    {
        return sequenceName;
    }
    
    public void setSequenceName(String sequenceName)
    {
        this.sequenceName = sequenceName;
    }
    
    public Logger getLogger()
    {
        return logger;
    }
    
    public void setLogger(Logger logger)
    {
        this.logger = logger;
    }

    public List<Map<String, String>> getConfigList()
    {
        return configList;
    }
    
    public void setConfigList(List<Map<String, String>> configList)
    {
        this.configList = configList;
    }
    
}
